// WebSocket 连接相关功能
import { Ref } from 'vue';
import websocketService from '../services/websocket';
import { storageGet, isTauri } from '../services/secure-storage';
import type { Message, ConnectionStatus } from './chat-types';
import { handleIncomingMessage } from './chat-message-processor';
import { storageSet } from '../services/secure-storage';

/**
 * 初始化 WebSocket 监听器
 */
export function createWebSocketHandlers(
  isConnected: Ref<boolean>,
  connectionStatus: Ref<ConnectionStatus>,
  currentUserId: Ref<string | null>,
  subscriptionId: Ref<string | null>,
  currentTargetId: Ref<string | null>,
  targetType: Ref<'User' | 'Group'>,
  messages: Ref<Message[]>,
  saveMessagesToStorage: () => Promise<void>,
  loadMessagesFromStorage: () => Promise<void>,
  getDeletedMessageIds?: () => Promise<Set<string>>
) {
  let websocketInitialized = false;
  let connectedHandler: (() => Promise<void>) | null = null;
  let disconnectedHandler: (() => void) | null = null;
  let messageHandler: ((message: any) => Promise<void>) | null = null;
  let errorHandler: ((error: Error) => void) | null = null;

  const initWebSocket = () => {
    // 如果已经初始化过，先移除旧的监听器
    if (websocketInitialized) {
      console.log('⚠️ WebSocket 监听器已初始化，先移除旧的监听器');
      if (connectedHandler) {
        websocketService.off('connected', connectedHandler);
      }
      if (disconnectedHandler) {
        websocketService.off('disconnected', disconnectedHandler);
      }
      if (messageHandler) {
        websocketService.off('message', messageHandler);
      }
      if (errorHandler) {
        websocketService.off('error', errorHandler);
      }
    }

    // 定义事件处理函数
    connectedHandler = async () => {
      isConnected.value = true;
      connectionStatus.value = 'connected';
      
      console.log('WebSocket 已连接，MQTT broker 会自动推送离线消息');
      console.log('当前用户ID:', currentUserId.value);
      console.log('订阅ID:', subscriptionId.value);
      
      // 等待一小段时间，让broker有时间推送离线消息
      setTimeout(async () => {
        try {
          const { getUserChats } = await import('../services/im-chat');
          const chats = await getUserChats();
          console.log('WebSocket连接后，检查是否有新的聊天记录:', chats.length, '个聊天');
          
          const { getUnreadStats } = await import('../services/im-chat');
          const unreadStats = await getUnreadStats();
          console.log('检测到未读消息:', unreadStats);
          
          // 重要：由于后端可能过滤了语音和视频消息（离线时不推送，只存储），
          // 我们需要主动获取所有聊天记录的离线消息，而不仅仅是有未读统计的
          // 这样可以确保获取到所有类型的消息，包括被过滤的语音和视频消息
          const { getSingleMessages, getGroupMessages } = await import('../services/im-message');
          
          // 检查本地缓存是否为空，如果为空，只同步当天的消息
          const hasLocalCache = messages.value.length > 0;
          let sinceSequence: number | undefined = undefined;
          
          if (!hasLocalCache) {
            // 缓存为空时，只同步当天的消息（避免同步历史很久的数据）
            const todayStart = new Date();
            todayStart.setHours(0, 0, 0, 0);
            sinceSequence = todayStart.getTime();
            console.log('本地缓存为空，只同步当天的消息，时间戳:', sinceSequence);
          }
          
          // 获取所有聊天记录，主动拉取离线消息（包括被后端过滤的语音和视频消息）
          const chatsToFetch = chats.filter(chat => {
            // 只获取单聊和群聊
            return chat.chat_type === 1 || chat.chat_type === 2;
          });
          
          console.log('准备主动获取离线消息，聊天记录数量:', chatsToFetch.length);
          
          // 如果有未读统计，优先获取未读的聊天记录
          const unreadChatIds = new Set<string>();
          if (unreadStats && unreadStats.unread_chats && unreadStats.unread_chats.length > 0) {
            for (const unreadChat of unreadStats.unread_chats) {
              unreadChatIds.add(String(unreadChat.to_id));
            }
            console.log('检测到未读消息，优先获取未读聊天记录:', unreadChatIds.size, '个');
          }
          
          // 先获取未读的聊天记录，再获取其他的
          const sortedChats = [...chatsToFetch].sort((a, b) => {
            const aIsUnread = unreadChatIds.has(String(a.to_id));
            const bIsUnread = unreadChatIds.has(String(b.to_id));
            if (aIsUnread && !bIsUnread) return -1;
            if (!aIsUnread && bIsUnread) return 1;
            return 0;
          });
          
          for (const chat of sortedChats) {
            // 定义 chatName 在 try 块外，以便在 catch 块中使用
            const chatName = chat.chat_type === 1 
              ? (chats.find(c => c.to_id === chat.to_id && c.chat_type === 1)?.name || chat.to_id)
              : (chats.find(c => c.to_id === chat.to_id && c.chat_type === 2)?.name || chat.to_id);
            
            try {
              let fetchedMessages: any[] = [];
              
              // 对于有未读消息的聊天，获取更多消息（100条），确保能获取到所有离线消息
              // 对于没有未读消息的聊天，也获取消息（50条），以防有被过滤的消息
              const limit = unreadChatIds.has(String(chat.to_id)) ? 100 : 50;
              
              if (chat.chat_type === 1) {
                fetchedMessages = await getSingleMessages(String(chat.to_id), sinceSequence, limit);
              } else if (chat.chat_type === 2) {
                fetchedMessages = await getGroupMessages(String(chat.to_id), sinceSequence, limit);
              }
              
              console.log(`获取到 ${chatName} 的消息:`, fetchedMessages.length, '条', `(limit: ${limit})`);
                
              // 处理获取的消息
              for (const msg of fetchedMessages) {
                // 转换消息格式：从API格式转换为统一的消息格式
                let normalizedMsg: any = msg;
                
                if (chat.chat_type === 2) {
                  // 群组消息：从 ImGroupMessage 格式转换为统一格式
                  // 对于文件消息，file_url 应该从 message_body 中提取（如果 message_body 是 URL）
                  const isFileMessage = msg.message_content_type === 3;
                  const messageBodyIsUrl = msg.message_body && (
                    msg.message_body.startsWith('http://') || 
                    msg.message_body.startsWith('https://') || 
                    msg.message_body.startsWith('/api/upload/')
                  );
                  
                  normalizedMsg = {
                    message_id: msg.message_id,
                    from_user_id: msg.from_id, // from_id -> from_user_id
                    to_user_id: msg.group_id,  // group_id -> to_user_id
                    message: msg.message_body, // message_body -> message
                    timestamp_ms: msg.message_time, // message_time -> timestamp_ms
                    timestamp: msg.message_time,
                    file_url: (isFileMessage && messageBodyIsUrl) 
                      ? msg.message_body 
                      : (msg.extra ? (() => {
                          try {
                            const extra = JSON.parse(msg.extra);
                            return extra.file_url;
                          } catch {
                            return undefined;
                          }
                        })() : undefined),
                    file_name: msg.extra ? (() => {
                      try {
                        const extra = JSON.parse(msg.extra);
                        return extra.file_name;
                      } catch {
                        return undefined;
                      }
                    })() : undefined,
                    file_type: msg.extra ? (() => {
                      try {
                        const extra = JSON.parse(msg.extra);
                        return extra.file_type;
                      } catch {
                        return undefined;
                      }
                    })() : undefined,
                    message_content_type: msg.message_content_type,
                    chat_type: 2, // 明确设置为群聊
                  };
                } else {
                  // 单聊消息：从 ImSingleMessage 格式转换为统一格式
                  // 对于文件消息，file_url 应该从 message_body 中提取（如果 message_body 是 URL）
                  const isFileMessage = msg.message_content_type === 3;
                  const messageBodyIsUrl = msg.message_body && (
                    msg.message_body.startsWith('http://') || 
                    msg.message_body.startsWith('https://') || 
                    msg.message_body.startsWith('/api/upload/')
                  );
                  
                  normalizedMsg = {
                    message_id: msg.message_id,
                    from_user_id: msg.from_id, // from_id -> from_user_id
                    to_user_id: msg.to_id,     // to_id -> to_user_id
                    message: msg.message_body, // message_body -> message
                    timestamp_ms: msg.message_time, // message_time -> timestamp_ms
                    timestamp: msg.message_time,
                    file_url: (isFileMessage && messageBodyIsUrl) 
                      ? msg.message_body 
                      : (msg.extra ? (() => {
                          try {
                            const extra = JSON.parse(msg.extra);
                            return extra.file_url;
                          } catch {
                            return undefined;
                          }
                        })() : undefined),
                    file_name: msg.extra ? (() => {
                      try {
                        const extra = JSON.parse(msg.extra);
                        return extra.file_name;
                      } catch {
                        return undefined;
                      }
                    })() : undefined,
                    file_type: msg.extra ? (() => {
                      try {
                        const extra = JSON.parse(msg.extra);
                        return extra.file_type;
                      } catch {
                        return undefined;
                      }
                    })() : undefined,
                    message_content_type: msg.message_content_type,
                    chat_type: 1, // 明确设置为单聊
                  };
                }
                
                // 重要：过滤掉通话邀请消息（message_content_type === 4）
                // 通话邀请是实时消息，不应该在离线消息加载时处理，避免弹出过期的通话邀请
                // 同时检查原始消息和规范化消息的 message_content_type
                const isCallInvite = msg.message_content_type === 4 || normalizedMsg.message_content_type === 4;
                if (isCallInvite) {
                  console.log('🚫 过滤掉离线通话邀请消息（不处理，避免弹出过期邀请）:', {
                    message_id: normalizedMsg.message_id,
                    original_message_content_type: msg.message_content_type,
                    normalized_message_content_type: normalizedMsg.message_content_type,
                    chat_type: normalizedMsg.chat_type,
                    from_user_id: normalizedMsg.from_user_id,
                    to_user_id: normalizedMsg.to_user_id,
                    timestamp: normalizedMsg.timestamp_ms || normalizedMsg.timestamp,
                    reason: '通话邀请是实时消息，离线加载时不应处理'
                  });
                  continue; // 跳过通话邀请消息，不处理
                }
                
                // 重要：记录消息类型，用于调试（特别是语音和视频消息）
                if (import.meta.env.DEV && (msg.message_content_type === 5 || msg.message_content_type === 6)) {
                  console.log('📥 获取到语音/视频离线消息:', {
                    message_id: normalizedMsg.message_id,
                    message_content_type: msg.message_content_type,
                    chat_type: normalizedMsg.chat_type,
                    from_user_id: normalizedMsg.from_user_id,
                    to_user_id: normalizedMsg.to_user_id,
                  });
                }
                
                // 确保离线消息的 isReceived 标志正确设置
                // 对于单聊离线消息，需要特别处理：to_id 是当前用户，from_id 是好友
                const currentUserIdStr = String(currentUserId.value || '');
                const currentOpenId = localStorage.getItem('openId') || '';
                const msgFromId = String(normalizedMsg.from_user_id || '');
                const msgToId = String(normalizedMsg.to_user_id || '');
                
                // 检查是否是当前用户发送的消息
                const isFromCurrentUser = msgFromId === currentUserIdStr || 
                  msgFromId === currentOpenId;
                
                // 检查 to_id 是否是当前用户（对于单聊，to_id 应该是接收方）
                let isToCurrentUser = false;
                if (normalizedMsg.chat_type === 1) {
                  // 单聊：to_id 应该是当前用户
                  isToCurrentUser = msgToId === currentUserIdStr || 
                                   msgToId === currentOpenId;
                  
                  if (!isToCurrentUser) {
                    try {
                      const userStr = localStorage.getItem('user') || '{}';
                      const user = JSON.parse(userStr);
                      isToCurrentUser = msgToId === (user.open_id || '') || 
                                       msgToId === (user.name || '');
                    } catch (e) {
                      // 解析失败，忽略
                    }
                  }
                }
                
                // 对于单聊离线消息，如果 to_id 是当前用户且 from_id 不是当前用户，说明是接收的消息
                if (normalizedMsg.chat_type === 1 && isToCurrentUser && !isFromCurrentUser) {
                  console.log('📥 处理单聊离线消息（接收）:', {
                    message_id: normalizedMsg.message_id,
                    from_user_id: msgFromId,
                    to_user_id: msgToId,
                    chat_type: normalizedMsg.chat_type,
                    message_content_type: normalizedMsg.message_content_type,
                    isFromCurrentUser,
                    isToCurrentUser,
                  });
                } else if (normalizedMsg.chat_type === 2 && !isFromCurrentUser) {
                  console.log('📥 处理群聊离线消息（接收）:', {
                    message_id: normalizedMsg.message_id,
                    from_user_id: msgFromId,
                    to_user_id: msgToId,
                    chat_type: normalizedMsg.chat_type,
                    message_content_type: normalizedMsg.message_content_type,
                  });
                }
                
                await handleIncomingMessage(
                  normalizedMsg,
                  messages,
                  currentUserId,
                  currentTargetId,
                  targetType,
                  saveMessagesToStorage,
                  getDeletedMessageIds
                );
              }
                
              await saveMessagesToStorage();
            } catch (error) {
              console.error(`获取 ${chatName} 的消息失败:`, error);
            }
          }
          
          const receivedCount = messages.value.filter(m => m.isReceived).length;
          const sentCount = messages.value.filter(m => !m.isReceived).length;
          console.log('✅ 主动获取消息完成:', {
            totalMessages: messages.value.length,
            receivedMessages: receivedCount,
            sentMessages: sentCount,
            currentTargetId: currentTargetId.value,
            targetType: targetType.value,
            fetchedChatsCount: sortedChats.length,
          });
        } catch (error) {
          console.warn('检查聊天记录失败:', error);
        }
      }, 2000);
    };

    disconnectedHandler = () => {
      isConnected.value = false;
      connectionStatus.value = 'disconnected';
    };

    messageHandler = async (message: any) => {
      // 减少日志输出，只在需要调试时启用
      // console.log('🟢 === ChatStore 收到消息 ===');
      // console.log('🟢 ChatStore 消息对象:', message);
      
      await handleIncomingMessage(
        message,
        messages,
        currentUserId,
        currentTargetId,
        targetType,
        saveMessagesToStorage,
        getDeletedMessageIds
      );
    };

    errorHandler = (error: Error) => {
      const errorMessage = error.message || '';
      if (errorMessage.includes('连接被重置') || errorMessage.includes('connection reset')) {
        console.log('WebSocket 连接被重置，正在自动重连...');
      } else {
        console.error('WebSocket 错误:', error);
        connectionStatus.value = 'error';
      }
    };

    // 注册事件监听器
    if (connectedHandler) {
      websocketService.on('connected', connectedHandler);
    }
    if (disconnectedHandler) {
      websocketService.on('disconnected', disconnectedHandler);
    }
    if (messageHandler) {
      websocketService.on('message', messageHandler);
    }
    if (errorHandler) {
      websocketService.on('error', errorHandler);
    }

    websocketInitialized = true;
    console.log('✅ WebSocket 监听器已初始化');
  };

  const connect = async (subId: string) => {
    if (subId == null || subId === undefined || subId.trim() === '') {
      throw new Error('订阅ID不能为空');
    }

    const newOpenId = isTauri()
      ? await storageGet('openId')
      : localStorage.getItem('openId');
    
    if (!newOpenId) {
      console.warn('⚠️ 未找到 openId，可能未登录或登录信息已过期');
      throw new Error('未找到用户标识符，请重新登录');
    }
    
    const oldOpenId = currentUserId.value;
    
    // 保存当前消息
    if (oldOpenId && messages.value.length > 0) {
      console.log('连接前保存当前消息，用户ID:', oldOpenId, '消息数:', messages.value.length);
      const oldStorageKey = `chat_messages_${oldOpenId}`;
      const oldMessagesValue = JSON.stringify(messages.value);
      if (isTauri()) {
        await storageSet(oldStorageKey, oldMessagesValue);
      } else {
        localStorage.setItem(oldStorageKey, oldMessagesValue);
      }
      console.log('已保存消息到存储:', oldStorageKey);
    }
    
    // 如果用户ID发生了变化
    if (oldOpenId && newOpenId && oldOpenId !== newOpenId) {
      console.log('检测到用户切换，清空内存消息:', oldOpenId, '->', newOpenId);
      messages.value = [];
      currentTargetId.value = null;
      targetType.value = 'User';
    }
    
    // 更新 currentUserId
    if (newOpenId) {
      if (currentUserId.value !== newOpenId) {
        console.log('更新 currentUserId:', currentUserId.value, '->', newOpenId);
      }
      currentUserId.value = newOpenId;
    }

    // 如果已经连接且是同一个订阅 ID，不重复连接
    if (isConnected.value && subscriptionId.value === subId) {
      console.log('WebSocket 已连接，跳过重复连接');
      return;
    }

    // 如果正在连接且是同一个订阅 ID，不重复连接
    if (connectionStatus.value === 'connecting' && subscriptionId.value === subId) {
      console.log('WebSocket 正在连接中，跳过重复连接');
      return;
    }

    // 如果正在连接或已连接到不同的订阅 ID，先断开
    if (connectionStatus.value === 'connecting' || (isConnected.value && subscriptionId.value !== subId)) {
      console.log('检测到订阅ID变化，先断开旧连接:', subscriptionId.value, '->', subId);
      
      if (currentUserId.value && messages.value.length > 0) {
        const oldStorageKey = `chat_messages_${currentUserId.value}`;
        const oldMessagesValue = JSON.stringify(messages.value);
        if (isTauri()) {
          await storageSet(oldStorageKey, oldMessagesValue);
        } else {
          localStorage.setItem(oldStorageKey, oldMessagesValue);
        }
        console.log('✅ 已保存旧用户消息到隔离存储:', {
          storageKey: oldStorageKey,
          messageCount: messages.value.length,
          userId: currentUserId.value
        });
        messages.value = [];
      }
      
      await websocketService.disconnect();
      await new Promise(resolve => setTimeout(resolve, 100));
      subscriptionId.value = subId;
      connectionStatus.value = 'connecting';
      
      // 连接前恢复新用户的消息
      await loadMessagesFromStorage();
      await websocketService.connect(subId);
      return;
    }

    subscriptionId.value = subId;
    connectionStatus.value = 'connecting';
    
    // 设置当前用户ID
    if (!currentUserId.value) {
      const openId = isTauri()
        ? await storageGet('openId')
        : localStorage.getItem('openId');
      if (openId) {
        currentUserId.value = openId;
      }
    }
    
    // 连接前恢复消息
    await loadMessagesFromStorage();
    await websocketService.connect(subId);
  };

  const disconnect = async (clearMessages = false) => {
    if (!clearMessages) {
      await saveMessagesToStorage();
    }
    
    await websocketService.disconnect();
    
    if (clearMessages) {
      messages.value = [];
    }
    
    if (clearMessages) {
      currentUserId.value = null;
      subscriptionId.value = null;
      currentTargetId.value = null;
    }
    
    isConnected.value = false;
    connectionStatus.value = 'disconnected';
  };

  return {
    initWebSocket,
    connect,
    disconnect
  };
}

